package com.gitee.wsl.mathematics.vector.vec4

import com.gitee.wsl.ext.array.FloatArray
import com.gitee.wsl.io.dataproxy.DataProxy
import com.gitee.wsl.io.dataproxy.asProxy
import com.gitee.wsl.mathematics.vector.vec2.MutableVec2f
import com.gitee.wsl.mathematics.vector.vec3.MutableVec3f


/**
 * A class representing a four-dimensional vector.
 */
class MutableVec4f(override val proxy: DataProxy<Float>): Vec4f(proxy=proxy), MutableVector4F<Vec4f> {
    constructor(x: Float=0.0f,
                y: Float=0.0f,
                z: Float=0.0f,
                w: Float=0.0f):this(FloatArray(x,y,z,w).asProxy())
    constructor(a: Number) : this(a.toFloat(), a.toFloat(), a.toFloat(), a.toFloat())
    constructor(x: Number, y: Number, z: Number, w: Number) : this(x.toFloat(), y.toFloat(), z.toFloat(), w.toFloat())
    constructor(base: Vec4f) : this(base.x, base.y, base.z, base.w)
    constructor(base: Vector4<*,*>) : this(base.x, base.y, base.z, base.w)

    //override val mutex: Mutex = Mutex()

    override val self
        get() = this

    override fun createVec2(a: Float, b: Float):MutableVec2f = MutableVec2f(a,b)

    override fun createVec3(a: Float, b: Float, c: Float):MutableVec3f = MutableVec3f(a,b,c)

    override fun create(x: Float, y: Float, z: Float, w: Float): MutableVec4f = MutableVec4f(x, y, z, w)

    companion object {
        val one get() = MutableVec4f(1.0, 1.0, 1.0, 1.0)
        val zero get() = MutableVec4f(0.0, 0.0, 0.0, 0.0)
        val right get() = MutableVec4f(1.0, 0.0, 0.0, 0.0)
        val left get() = MutableVec4f(-1.0, 0.0, 0.0, 0.0)
        val up get() = MutableVec4f(0.0, 1.0, 0.0, 0.0)
        val down get() = MutableVec4f(0.0, -1.0, 0.0, 0.0)
        val forward get() = MutableVec4f(0.0, 0.0, 1.0, 0.0)
        val backward get() = MutableVec4f(0.0, 0.0, -1.0, 0.0)
        val negativeInfinity get() = MutableVec4f(Float.NEGATIVE_INFINITY)
        val positiveInfinity get() = MutableVec4f(Float.POSITIVE_INFINITY)
    }

    /**Reflects the vector from [normal].*/
   /*override infix fun reflectFrom(normal: Vec4f): MutableVec4f {
        val norm = normal.normalized
        val factor = -2.0 * this dot norm
        return MutableVec4f(factor * norm + this)
    }
    *//**Reflects the vector from [normal].*//*
    override infix fun reflectFrom(normal: Vec3f) = reflectFrom(normal.vec4)
    *//**Reflects the vector from [normal].*//*
    override infix fun reflectFrom(normal: Vec2f) = reflectFrom(normal.vec4)*/

    override fun equals(other: Any?) = other is MutableVec4f && x == other.x && y == other.y && z == other.z && w == other.w
    override fun hashCode() = 31 * (31 * (31 * x.hashCode() + y.hashCode()) + z.hashCode()) + w.hashCode()
}